/*
Designed By Theekshana Wickramathilake
SCL B6
SDA B7

------  I2C1   --------
 */
/* Includes -----------------------------------------------------------------------*/
#include "I2CDRIVER.h"
#include <stm32f4xx.h>
#include <stm32f4xx_i2c.h>

/* Private constants --------------------------------------------------------------*/

#define Accel_ADDRESS 0x1D

/* Private functions --------------------------------------------------------------*/
void init_I2C1(void){
	GPIO_InitTypeDef GPIO_InitStruct;
	I2C_InitTypeDef I2C_InitStruct;
	// enable APB1 peripheral clock for I2C1
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	// enable clock for SCL and SDA pins
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // PB6 and PB7
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;			// set pins to alternate function
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;		// set GPIO speed
	GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;			// set output to open drain --> the line has to be only pulled low, not driven high
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;			// enable pull up resistors
	GPIO_Init(GPIOB, &GPIO_InitStruct);					// init GPIOB
	// Connect I2C1 pins to AF
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);	// SCL
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); // SDA
	// configure I2C1
	I2C_InitStruct.I2C_ClockSpeed = 800000; 		// 800kHz
	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;			// I2C mode
	I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;	// 50% duty cycle --> standard
	I2C_InitStruct.I2C_OwnAddress1 = 0x00;			// own address, not relevant in master mode
	I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;		// disable acknowledge when reading (can be changed later on)
	I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
	I2C_Init(I2C1, &I2C_InitStruct);				// init I2C1
	// enable I2C1
	I2C_Cmd(I2C1, ENABLE);


}

void setupaccel(){
	I2C_Write_Byte(I2C1,0x20,0b10100111,Accel_ADDRESS<<1); // 01110111 Normal Power Mode / XYZ enable Normal Power Mode ctrl 1
	I2C_Write_Byte(I2C1,0x21,0b11000000,Accel_ADDRESS<<1); // 00101000 high resolution 2g ctrl4
	I2C_Write_Byte(I2C1,0x24,0b11110100,Accel_ADDRESS<<1);
}




void I2C_Write_Byte(I2C_TypeDef* I2Cx ,int reg_addr , int reg_data, uint8_t dev_Addr)
{

	while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));/* While the bus is busy */


	I2C_GenerateSTART(I2Cx, ENABLE);/* Send I2C1 START condition */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));


	I2C_Send7bitAddress(I2Cx, dev_Addr , I2C_Direction_Transmitter);/* Send Device slave Address for write */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));


	I2C_SendData(I2Cx, reg_addr);/* Send the Device internal register address */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));


	I2C_SendData(I2Cx, reg_data);
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

	I2C_AcknowledgeConfig(I2Cx, DISABLE);/* Disable Acknowledgement */

	I2C_GenerateSTOP(I2Cx, ENABLE);/* Send I2C1 STOP Condition */


	I2C_AcknowledgeConfig(I2Cx,ENABLE);/* Enable Acknowledgement to be ready for another reception */
}

uint8_t I2C_Read_Byte(I2C_TypeDef* I2Cx, int reg_addr,int dev_Addr)
{
	int Red_reg;


	while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));/* While the bus is busy */

	I2C_GenerateSTART(I2Cx, ENABLE);/* Send I2C1 START condition */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));


	I2C_Send7bitAddress(I2Cx, dev_Addr, I2C_Direction_Transmitter);/* Send Device slave Address for write */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));


	I2C_SendData(I2Cx, reg_addr);/* Send the Device internal register address */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));



	I2C_GenerateSTART(I2Cx, ENABLE);/* Send STRAT condition a second time called repeated start*/
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

	I2C_Send7bitAddress(I2Cx, (dev_Addr | 0x01) , I2C_Direction_Receiver);/* Send Device slave Address for read */
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));

	Red_reg = I2C_ReceiveData(I2Cx);

	I2C_AcknowledgeConfig(I2Cx, DISABLE);/* Disable Acknowledgement */

	I2C_GenerateSTOP(I2Cx, ENABLE);/* Send I2C1 STOP Condition */

	return Red_reg;/*Return data which is to be read from device*/
}


void Delay(__IO uint32_t nCount) {
  while(nCount--) {
  }
}
